package math

import (
	"go_gvm_mini/instructions/base"
	"go_gvm_mini/rtda"
	"reflect"
	"strings"
)

type SUBTRACT[T interface{}] struct {
	base.NoOperandsInstruction
}

func (self *SUBTRACT[T]) Execute(jFrame *rtda.JFrame) {
	stack := jFrame.OperandStack()
	e := reflect.TypeOf(self).Elem().String()
	etype := strings.ReplaceAll(strings.Split(e, "[")[1], "]", "")
	switch etype {
	case "int64":
		stack.PushLong(-stack.PopLong() + stack.PopLong())
		break
	case "int32":
		stack.PushInt(-stack.PopInt() + stack.PopInt())
		break
	case "float32":
		stack.PushFloat(-stack.PopFloat() + stack.PopFloat())
		break
	case "float64":
		stack.PushDouble(-stack.PopDouble() + stack.PopDouble())
		break
	}
}

type DSUB struct {
	SUBTRACT[float64]
}

type FSUB struct {
	SUBTRACT[float32]
}

type ISUB struct {
	SUBTRACT[int32]
}

type LSUB struct {
	SUBTRACT[int64]
}
